React 文档
导读与全书目录表:见同目录 01-React 入门:简介·特性与设计范式.md 开头。
高阶组件
- 高阶组件(Higher-Order Component)是React中用于复用组件逻辑的一种高级技巧。HOC本质上是一个纯函数,它接收一个或多个组件并返回一个新的组件。
- 类似 vue2 中的混入 mixins,React 16.8引入的更简单的逻辑复用方式,很多HOC场景可以用自定义Hook替代
作用
增强当前组件的功能,逻辑复用
约定
- 不要以任何方式修改原始组件
- props 保持一致
- 不要在render中使用高阶组件,这会导致每次渲染时组件都会卸载和重新挂载
- ref 指向的是外层的容器组件,如果要使用,需要借助 React.forwardRef
使用场景
- 处理组件逻辑复用 & 状态管理 & 事件处理等场景
- loading 条件渲染
- 数据校验
- 权限校验
- 异常处理
- 通用方法共享
常见模式
- 事件处理高阶函数
ts
function withLogging(fn) {
return function(...args) {
console.log('函数被调用,参数:', args);
return fn(...args);
};
}
// 使用
const handleClickWithLog = withLogging((event) => {
console.log('按钮被点击');
});
<button onClick={handleClickWithLog}>点击我</button>- 数据转换高阶函数
ts
function withDataTransform(transformFn) {
return function(data) {
const transformed = transformFn(data);
console.log('转换前:', data, '转换后:', transformed);
return transformed;
};
}
// 使用
const formatUserData = withDataTransform((user) => ({
fullName: `${user.firstName} ${user.lastName}`,
age: new Date().getFullYear() - user.birthYear
}));- 异步操作高阶函数
ts
function withAsyncHandling(fn) {
return async function(...args) {
try {
const result = await fn(...args);
return result;
} catch (error) {
console.error('异步操作失败:', error);
throw error;
}
};
}
// 使用
const fetchDataWithHandling = withAsyncHandling(async (url) => {
const response = await fetch(url);
return response.json();
});实际使用
- 组件逻辑复用(高阶组件 HOC)
ts
// 高阶组件示例:添加加载状态
function withLoading(Component) {
return function EnhancedComponent({ isLoading, ...props }) {
if (isLoading) {
return <div>Loading...</div>;
}
return <Component {...props} />;
};
}
// 使用 HOC
function UserList({ users }) {
return (
<ul>
{users.map(user => (
<li key={user.id}>{user.name}</li>
))}
</ul>
);
}
// 增强后的组件
const UserListWithLoading = withLoading(UserList);
// 使用时传入 isLoading 控制状态
<UserListWithLoading isLoading={false} users={[]} />- 表单处理高阶函数
ts
function createInputHandler(setState) {
return function(event) {
const { name, value } = event.target;
setState(prev => ({ ...prev, [name]: value }));
};
}
// 在组件中使用
function MyForm() {
const [formData, setFormData] = useState({ username: '', password: '' });
const handleInputChange = createInputHandler(setFormData);
return (
<form>
<input name="username" onChange={handleInputChange} />
<input name="password" onChange={handleInputChange} />
</form>
);
}- 防抖/节流 事件处理高阶函数
ts
function withDebounce(fn, delay) {
let timer;
return function(...args) {
clearTimeout(timer);
timer = setTimeout(() => fn(...args), delay);
};
}
// 使用
function SearchComponent() {
const [query, setQuery] = useState('');
const handleSearch = useCallback(withDebounce((searchTerm) => {
console.log('搜索:', searchTerm);
// 执行搜索API调用
}, 500), []);
const handleChange = (e) => {
setQuery(e.target.value);
handleSearch(e.target.value);
};
return <input value={query} onChange={handleChange} />;
}总结
- 高阶组件是React中强大的代码复用模式,特别适合横切关注点(cross-cutting concerns)的处理。
- 虽然Hooks的引入减少了对HOC的需求,但在某些场景下HOC仍然是有效的解决方案,特别是在需要增强或修改组件行为时。
注意
- 避免过度使用:过多嵌套的高阶函数会降低代码可读性(如 "回调地狱" 类似问题)。
- 与 Hooks 配合:在现代 React 中,Hooks(如 useCallback、useMemo)常与高阶函数结合使用,优化性能。
- 命名规范:高阶组件通常以 with 为前缀(如 withLoading),清晰表达其增强功能。
react 高阶组件和使用场景
回答
shell
# 概念
“高阶组件 HOC 是一种复用组件逻辑的设计模式,本质是接收一个组件作为参数,返回一个增强后的新组件的纯函数
# 使用场景
常见用于通用数据请求、权限控制、埋点监控、样式增强等跨组件逻辑复用场景
1. 通用数据获取 --- 避免重复写接口请求逻辑
“比如多个组件都需要获取用户信息 / 商品列表,可封装 withFetch 高阶组件,统一处理请求、加载、错误状态,组件只需关注渲染,减少重复代码。”
2. 权限控制 --- 统一校验用户权限
“封装 withAuth 高阶组件,在组件挂载前校验用户是否登录 / 是否有操作权限,无权限则跳转到登录页,所有需要权限的组件只需包裹该 HOC 即可,无需逐个写校验逻辑。”
3. 埋点 / 日志监控 --- 统一处理行为埋点
“比如按钮点击、页面挂载的埋点逻辑,封装 withTrack 高阶组件,统一监听事件并上报,业务组件无需关心埋点细节,只需要传递埋点标识即可。”
4. 样式 / 主题增强 --- 统一注入样式 / 主题属性
“封装 withTheme 高阶组件,向组件注入全局主题变量(如颜色、字体),所有需要适配主题的组件只需包裹该 HOC,即可统一使用主题样式,便于主题切换。
# HOC 的注意事项
“使用 HOC 时要注意避免修改原组件,保持纯函数特性;
同时不要在渲染阶段创建 HOC,否则会导致组件重复挂载;
另外,Hooks 虽然能替代部分 HOC 场景,但 HOC 在全局级别的逻辑复用(如权限控制)上仍有优势,二者可结合使用。”